package com.view.cn.mvprxjava.utils;

import android.graphics.Point;

import java.util.ArrayList;

/**
 * 算法工具类，用于计算五子连珠
 * Created by Zengxiaoping on 2016/12/14.
 */

public class PieceUtils {

	private static final int MAX_LINE_NUMBER = 10;      //棋盘最大行列数
	private static final int MAX_NUMBER_IN_LINE = 5;    //五子连珠游戏结束

	/**
	 * 检测五子连珠
	 *
	 * @param point    刚下的棋子
	 * @param dataList 检测刚下的棋子的选手的集合是否有五子连珠
	 * @return true:gameOver
	 */
	public static boolean checkFiveInLine(Point point, ArrayList<Point> dataList) {
		if (dataList.size() >= MAX_NUMBER_IN_LINE) {
			if (checkFiveInHorizontal(point, dataList)) {
				return true;
			}
			if (checkFiveInVertical(point, dataList)) {
				return true;
			}
			if (checkFiveInLeftDiagonal(point, dataList)) {
				return true;
			}
			if (checkFiveInRightDiagonal(point, dataList)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 检测横向五子连珠
	 *
	 * @param point    刚下的棋子
	 * @param dataList 检测刚下的棋子的选手的集合是否有五子连珠
	 * @return true:gameOver
	 */
	public static boolean checkFiveInHorizontal(Point point, ArrayList<Point> dataList) {
		int sumNumber = 0;                                                      //除掉刚下的子，其他能连成一线的棋子数量
		int i = 0;
		if (point!=null&&point.x != 0) {                                                     //刚下的棋子在左边边界，跳过左边检测
			while (i < Math.min(MAX_NUMBER_IN_LINE - 1, point.x)) {             //取小值（4，左边能下的棋子数）；最大值为4,最小为0
				if (dataList.contains(new Point(point.x - (i + 1), point.y))) { //依次往左根据刚下的棋子的X坐标-i，检测是否包涵棋手的棋子
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;                                     //i=5，不能满足下一次循环，跳出while循环
				}
			}
		}
		//重置i=0;
		i = 0;
		int leftSumNumber = sumNumber;                                          //leftSumNumber是左边已经存在连子数
		if (point!=null&&point.x != MAX_LINE_NUMBER - 1) {                                   //刚下的棋子在右边边界，跳过右边检测
			//i<某值【取小值（4-leftSumNumber，右边能下的棋子数）；最大值为4-leftSumNumber,最小为0】
			while (i < Math.min(MAX_NUMBER_IN_LINE - 1 - leftSumNumber, (MAX_LINE_NUMBER - 1) - point.x)) {
				if (dataList.contains(new Point(point.x + (i + 1), point.y))) { //依次往左根据刚下的棋子的X坐标-i，检测是否包涵棋手的棋子
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;                                     //i=5，不能满足下一次循环
				}
			}
		}
		//五子连珠
		if (sumNumber >= (MAX_NUMBER_IN_LINE - 1)) {
			return true;
		}
		return false;
	}

	/**
	 * 检测纵向五子连珠
	 *
	 * @param point    刚下的棋子
	 * @param dataList 检测刚下的棋子的选手的集合是否有五子连珠
	 * @return true:gameOver
	 */
	public static boolean checkFiveInVertical(Point point, ArrayList<Point> dataList) {
		int sumNumber = 0;
		int i = 0;
		if (point!=null&&point.y != 0) {
			while (i < Math.min(MAX_NUMBER_IN_LINE - 1, point.y)) {
				if (dataList.contains(new Point(point.x, (point.y - (i + 1))))) {
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;
				}
			}
		}
		i = 0;
		int topSumNumber = sumNumber;
		if (point!=null&&point.y != (MAX_LINE_NUMBER - 1)) {
			while (i < Math.min(MAX_NUMBER_IN_LINE - 1 - topSumNumber, (MAX_LINE_NUMBER - 1) - point.y)) {
				if (dataList.contains(new Point(point.x, point.y + (i + 1)))) {
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;
				}
			}
		}
		if (sumNumber >= (MAX_NUMBER_IN_LINE - 1)) {
			return true;
		}
		return false;
	}

	/**
	 * 检测左斜线五子连珠
	 *
	 * @param point    刚下的棋子
	 * @param dataList 检测刚下的棋子的选手的集合是否有五子连珠
	 * @return true:gameOver
	 */
	public static boolean checkFiveInLeftDiagonal(Point point, ArrayList<Point> dataList) {
		int sumNumber = 0;
		int i = 0;
		if (point!=null&&point.y != 0) {
			//三个值取最小
			int minNumber = (MAX_NUMBER_IN_LINE - 1) < point.y ? ((MAX_NUMBER_IN_LINE - 1) < point.x ?
					(MAX_NUMBER_IN_LINE - 1) : point.x) : (point.y < point.x ? point.y : point.x);
			while (i < minNumber) {
				if (dataList.contains(new Point(point.x - (i + 1), point.y - (i + 1)))) {
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;
				}
			}
		}
		i = 0;
		int subSumNumber = sumNumber;
		if (point!=null&&point.y != (MAX_LINE_NUMBER - 1)) {
			//同上，三个取最小
			int minNumber = Math.min(MAX_NUMBER_IN_LINE - 1 - subSumNumber, (MAX_LINE_NUMBER - 1) - point.y);
			minNumber = Math.min(minNumber, (MAX_LINE_NUMBER - 1) - point.x);
			while (i < minNumber) {
				if (dataList.contains(new Point(point.x + (i + 1), point.y + (i + 1)))) {
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;
				}
			}
		}
		if (sumNumber >= (MAX_NUMBER_IN_LINE - 1)) {
			return true;
		}
		return false;
	}

	/**
	 * 检测右斜线五子连珠
	 *
	 * @param point    刚下的棋子
	 * @param dataList 检测刚下的棋子的选手的集合是否有五子连珠
	 * @return true:gameOver
	 */
	public static boolean checkFiveInRightDiagonal(Point point, ArrayList<Point> dataList) {
		int sumNumber = 0;
		int i = 0;
		if (point!=null&&point.y != 0) {
			//三个值取最小
			int minNumber = Math.min(MAX_NUMBER_IN_LINE - 1, point.x);
			minNumber = Math.min(minNumber, (MAX_LINE_NUMBER - 1) - point.y);
			while (i < minNumber) {
				if (dataList.contains(new Point(point.x - (i + 1), point.y + (i + 1)))) {
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;
				}
			}
		}
		i = 0;
		int subSumNumber = sumNumber;
		if (point!=null&&point.y != (MAX_LINE_NUMBER - 1)) {
			//同上，三个取最小
			int minNumber = Math.min(MAX_NUMBER_IN_LINE - 1 - subSumNumber, point.y);
			minNumber = Math.min(minNumber, (MAX_LINE_NUMBER - 1) - point.x);
			while (i < minNumber) {
				if (dataList.contains(new Point(point.x + (i + 1), point.y - (i + 1)))) {
					++sumNumber;
					++i;
				} else {
					i = MAX_NUMBER_IN_LINE;
				}
			}
		}
		if (sumNumber >= (MAX_NUMBER_IN_LINE - 1)) {
			return true;
		}
		return false;
	}
}
